package run.scenario;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;

import log.LogConstants;


public class Scenario {
	
	protected HashMap<String, String> constants = new HashMap<String, String>();
	
	protected ArrayList<HashMap<String, String>> data = new ArrayList<HashMap<String,String>>();
	
	protected HashMap<Integer, Integer> participantLines = new HashMap<Integer, Integer>();
	
	protected HashMap<String, String> factorValues = new HashMap<String, String>();
	
	protected int currentLine;
	
	public Scenario(String fileName) {
		
		try {
			
			BufferedReader reader = new BufferedReader(new FileReader(fileName));
			
			String line;
			currentLine = 0;
			
			while ( (line = reader.readLine()) != null) {
				
				if (line.startsWith(GeneratorConstants.COMMENT)) {
					continue;
				}
				
				if ( 
						!line.startsWith(LogConstants.Participant) 
						&& !line.startsWith(LogConstants.Block)
						&& !line.startsWith(LogConstants.Trial) ) {
					
					// Constante
					
					String[] split = line.split(GeneratorConstants.SEPARATOR);
					
					System.out.print("Constant: ");
					for (String s : split) {
						System.out.print(s + " : ");
					}
					System.out.println();
					
					constants.put(split[0], split[1]);
					
				} else {
					
					// Ligne de block ou trial
					
					data.add(new HashMap<String, String>());
					
					String[] split = line.split(GeneratorConstants.SEPARATOR);
					
					for (int i = 0 ; i < split.length - 1 ; i+=2) {
						
						data.get(currentLine).put(split[i], split[i+1]);
						
					}
					
					if ( line.startsWith(LogConstants.Participant) ) {
						
						int currentParticipant = new Integer(lookForValue(LogConstants.Participant, split)).intValue();
						participantLines.put(new Integer(currentParticipant), new Integer(currentLine));
						
					}
					
					currentLine++;
					
				}
				
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	
	public void start(int participantId) {
		
		currentLine = 0;
		
		/*
		 * the first line (Block) is read. Automatically reading the following.
		 */
		goOn();
		
	}
	
	public boolean goOn() {
		
		currentLine++;
		if (currentLine > Integer.parseInt(constants.get(LogConstants.NbTrials))) {
			// Finished. 
			System.out.println("Scenario finished.");
			return false;
		}
		
		// Getting all the available data about the block or trial
		
		for (Entry<String, String> entry : data.get(currentLine).entrySet()) {
			
			factorValues.put(entry.getKey(), entry.getValue());
			
		}
		
		// if it's a block, check that next line is not a block
		if ( data.get(currentLine).containsKey( LogConstants.Block ) ) {		// && !data.get(currentLine+1).containsKey( LogConstants.Block )
			
			goOn();
			
		} else if ( data.get(currentLine).containsKey( LogConstants.Participant ) || data.get(currentLine).isEmpty() ) {
			
			// Finished. 
			System.out.println("Scenario finished.");
			return false;
			
		}
		
		return true;
		
	}
	
	
	
	protected String lookForValue(String key, String[] splitLine) {
		
		for (int i = 0 ; i < splitLine.length ; i += 2) {
			
			if ( splitLine[i].equals(key) ) {
				
				return splitLine[i+1];
				
			}
			
		}
		
		return null;
		
	}
	
	public String getConstant(String constantName) {
		
		return constants.get(constantName);
		
	}
	
	public String getFactorValue(String factorName) {
		
		return factorValues.get(factorName);
		
	}
	
	/**
	 * Goes to the first scenario line where the specified key has the specified
	 * value, i.e. goTo("Block", "3").
	 * 
	 * @param key
	 * @param value
	 * @return		true if the line was reached, false either
	 */
	public boolean goTo(String key, String value) {
		
		System.out.println("Go to " + key + " = " + value);
		
		if (!factorValues.containsKey(key)) {
			System.err.println("Can't go to \"" + key + "\" = \"" + value + "\" : key doesn't exist.");
			return false;
		}
		
		while( goOn() && !factorValues.get(key).equalsIgnoreCase(value) ) {
			// Nothin'
		}
		
		return factorValues.get(key).equalsIgnoreCase(value);
		
	}
	
	/**
	 * Goes to the first scenario line where the value associated to the 
	 * specified changes, i.e. "go to the next block"
	 * 
	 * @param key
	 * @return		true if the line was reached, false either
	 */
	public boolean goToNext(String key) {
		
		System.out.println("Go to " + key );
		
		if (!factorValues.containsKey(key)) {
			System.err.println("Can't go to \"" + key + "\" : key doesn't exist.");
			return false;
		}
		
		String currentValue = factorValues.get(key);
		
		while( goOn() && factorValues.get(key).equalsIgnoreCase(currentValue) ) {
			// Nothin'
		}
		
		return !factorValues.get(key).equalsIgnoreCase(currentValue);
		
	}
	
}
